package com.ziq.zcamp.util.encrypt;


import com.ziq.zcamp.manager.GlobalContextManager;

import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AesVr {
    final String TAG = "Aes";
    final Charset UTF_8 = StandardCharsets.UTF_8;//编码格式
    final int AES_KEY_LENGTH = 16;//密钥长度16字节，128位
    // 算法名称
    final String AES_ALGORITHM = "AES";
    // 加解密算法/模式/填充方式
    final String AES_TRANSFORMATION = "AES/CBC/PKCS7Padding";
    //偏移量iv
    final String AES_IV = "miecampijghbgtip";

    final String AES_STRING = "abcdefghijklmnopqrstuvwxyz123456789";
    public String password;

    public AesVr() {
        password = initCampAESKey();
    }


    public String encode(String data) {
        byte[] encodeData = encodeAes(password.getBytes(StandardCharsets.UTF_8), data);
        return Base64Utils.encodeToString(encodeData);
    }

    public String decode(String data) {
        byte[] encodeData = Base64Utils.decode(data);
        return decodeAES(password.getBytes(StandardCharsets.UTF_8), encodeData);
    }

    public String getSecret() {
        try {
            InputStream inPublic = GlobalContextManager.INSTANCE.getResources().getAssets().open("vr_public_key.pem");
            PublicKey publicKey = RSAUtils.getPublicKey(inPublic);
            byte[] encryptByte = RSAUtils.encrypt(password.getBytes(StandardCharsets.UTF_8), publicKey);
            return Base64Utils.encodeToString(encryptByte);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public String rsaEncode(String data){
        try {
            InputStream inPublic = GlobalContextManager.INSTANCE.getResources().getAssets().open("vr_public_key.pem");
            PublicKey publicKey = RSAUtils.getPublicKey(inPublic);
            byte[] encryptByte = RSAUtils.encrypt(data.getBytes(StandardCharsets.UTF_8), publicKey);
            return Base64Utils.encodeToString(encryptByte);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 生成AES key
     *
     * @return AES key
     */
    private String initCampAESKey() {
        StringBuilder sb = new StringBuilder();
        int len = AES_STRING.length();
        int length = AES_KEY_LENGTH - "miecamp".length();
        for (int i = 0; i < length; i++) {
            sb.append(AES_STRING.charAt(getRandom(len - 1)));
        }
        sb.append("miecamp");
        return sb.toString();
    }

    private int getRandom(int count) {
        return (int) Math.round(Math.random() * (count));
    }

    /**
     * 使用AES加密
     *
     * @param aesKey AES Key
     * @param data   被加密的数据
     * @return AES加密后的数据
     */
    public byte[] encodeAes(byte[] aesKey, String data) {
        if (aesKey == null || aesKey.length != AES_KEY_LENGTH) {
            return null;
        }
        SecretKeySpec keySpec = new SecretKeySpec(aesKey, AES_ALGORITHM);
        try {
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(AES_IV.getBytes(UTF_8));
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            return cipher.doFinal(data.getBytes(UTF_8));
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 使用AES解密
     *
     * @param aesKey AES Key
     * @param data   被解密的数据
     * @return AES解密后的数据
     */
    public String decodeAES(byte[] aesKey, byte[] data) {
        if (aesKey == null || aesKey.length != AES_KEY_LENGTH) {
            return null;
        }
        SecretKeySpec keySpec = new SecretKeySpec(aesKey, AES_ALGORITHM);
        try {
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(AES_IV.getBytes(UTF_8));
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            return new String(cipher.doFinal(data), UTF_8);
        } catch (Exception e) {
        }
        return null;
    }


}
